package per.chao.mqtt.domain.repo;

import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import per.chao.mqtt.domain.facade.IMessageCache;
import per.chao.mqtt.domain.interfaces.repo.BaseRepo;
import per.chao.mqtt.domain.shared.store.DupPublishMessageStore;
import per.chao.mqtt.domain.util.TopicUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Description:
 *
 * @author W.Chao
 * @date 2021/6/20 14:32
 **/
@Component
@Slf4j
public class PublishMessageRepo extends BaseRepo<DupPublishMessageStore> {
	private static final String PUBLISH_MESSAGE_PREFIX = "publish::";

	@Autowired
	@Qualifier("redisCache")
	private IMessageCache iMessageCache;

	private static String prefix(String clientId) {
		return TopicUtil.prefix(PUBLISH_MESSAGE_PREFIX, clientId);
	}

	@Override
	public void put(String clientId, DupPublishMessageStore dupPublishMessageStore) {
		if (containsKey(clientId)) {
			@SuppressWarnings("unchecked")
			Map<Integer, DupPublishMessageStore> map = (Map<Integer, DupPublishMessageStore>) iMessageCache.get(prefix(clientId));
			map.put(dupPublishMessageStore.getMessageId(), dupPublishMessageStore);
		} else {
			Map<Integer, DupPublishMessageStore> newMap = Maps.newHashMap();
			newMap.put(dupPublishMessageStore.getMessageId(), dupPublishMessageStore);
			iMessageCache.put(prefix(clientId), newMap);
		}
	}

	@Override
	@Deprecated
	public DupPublishMessageStore get(String clientId) {
		return null;
	}

	public DupPublishMessageStore get(String clientId, int messageId) {
		@SuppressWarnings("unchecked")
		Map<Integer, DupPublishMessageStore> map = (Map<Integer, DupPublishMessageStore>) iMessageCache.get(prefix(clientId));
		return map.getOrDefault(messageId, null);
	}

	@SuppressWarnings("unchecked")
	public List<DupPublishMessageStore> getByClientId(String clientId) {
		return new ArrayList<>(((Map<Integer, DupPublishMessageStore>) iMessageCache.get(prefix(clientId))).values());
	}

	@Override
	public void remove(String clientId) {
		iMessageCache.remove(prefix(clientId));
	}

	public void remove(String clientId, int messageId) {
		@SuppressWarnings("unchecked")
		Map<Integer, DupPublishMessageStore> map = (Map<Integer, DupPublishMessageStore>) iMessageCache.get(prefix(clientId));
		map.remove(messageId);
		iMessageCache.put(prefix(clientId), map);
	}

	@Override
	public boolean containsKey(String clientId) {
		return iMessageCache.containsKey(prefix(clientId));
	}
}
